load("@aspect_rules_js//js:defs.bzl", "js_binary", "js_library", "js_run_binary")
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag", "string_flag")
load("@npm//:defs.bzl", "npm_link_all_packages")
load("@rules_cc//cc:defs.bzl", "cc_library")
load(
    "//bazel:core.bzl",
    "MLN_CORE_HEADERS",
    "MLN_CORE_SOURCE",
    "MLN_DRAWABLES_GL_HEADERS",
    "MLN_DRAWABLES_GL_SOURCE",
    "MLN_DRAWABLES_HEADERS",
    "MLN_DRAWABLES_MTL_HEADERS",
    "MLN_DRAWABLES_MTL_SOURCE",
    "MLN_DRAWABLES_SOURCE",
    "MLN_DRAWABLES_WEBGPU_HEADERS",
    "MLN_DRAWABLES_WEBGPU_SOURCE",
    "MLN_GENERATED_OPENGL_SHADER_HEADERS",
    "MLN_GENERATED_SHADER_HEADERS",
    "MLN_GENERATED_SHADER_SOURCE",
    "MLN_GENERATED_STYLE_SOURCE",
    "MLN_LAYER_PLUGIN_HEADERS",
    "MLN_LAYER_PLUGIN_SOURCE",
    "MLN_OPENGL_HEADERS",
    "MLN_OPENGL_SOURCE",
    "MLN_PRIVATE_GENERATED_STYLE_HEADERS",
    "MLN_PUBLIC_GENERATED_STYLE_HEADERS",
    "MLN_SHAPING_HARFBUZZ_SRCS",
)
load("//bazel:flags.bzl", "CPP_FLAGS", "MAPLIBRE_FLAGS")

# Generate code required by the core

js_run_binary(
    name = "generated_style_code",
    srcs = glob(
        ["**/*.ejs"],
        allow_empty = False,
    ),
    outs = MLN_PUBLIC_GENERATED_STYLE_HEADERS +
           MLN_PRIVATE_GENERATED_STYLE_HEADERS +
           MLN_GENERATED_STYLE_SOURCE,
    tool = ":generate-style-code-script",
)

js_run_binary(
    name = "generated_shaders",
    srcs = ["shaders/manifest.json"] + glob(
        ["shaders/*.glsl"],
        allow_empty = False,
    ),
    outs = MLN_GENERATED_SHADER_HEADERS +
           MLN_GENERATED_SHADER_SOURCE +
           MLN_GENERATED_OPENGL_SHADER_HEADERS,
    tool = ":generate-shader-code-script",
)

# This header only target strips the __generated__ prefix for the compiler
# search paths, making the location of generated code transparent to the build
cc_library(
    name = "mbgl-core-generated-public-artifacts",
    hdrs = [
               ":generated_shaders",
               ":generated_style_code",
           ] + MLN_PUBLIC_GENERATED_STYLE_HEADERS +
           MLN_GENERATED_SHADER_HEADERS +
           select({
               "//:metal_renderer": [],
               "//conditions:default": MLN_GENERATED_OPENGL_SHADER_HEADERS,
           }),
    visibility = ["//visibility:public"],
)

# ditto, but for private headers (under the src/ path)
cc_library(
    name = "mbgl-core-generated-private-artifacts",
    hdrs = [":generated_style_code"] + MLN_PRIVATE_GENERATED_STYLE_HEADERS,
    visibility = ["//visibility:private"],
)

# Generated source is inserted directly into the core target, no need to remove
# the prefix from the path.
cc_library(
    name = "mbgl-core",
    srcs = MLN_LAYER_PLUGIN_SOURCE +
           MLN_CORE_SOURCE +
           MLN_GENERATED_SHADER_SOURCE +
           MLN_GENERATED_STYLE_SOURCE + select({
        ":drawable_renderer": MLN_OPENGL_SOURCE + MLN_DRAWABLES_SOURCE + MLN_DRAWABLES_GL_SOURCE,
        ":metal_renderer": MLN_DRAWABLES_SOURCE + MLN_DRAWABLES_MTL_SOURCE,
        ":webgpu_renderer": MLN_DRAWABLES_SOURCE + MLN_DRAWABLES_WEBGPU_SOURCE,
        "//conditions:default": [],
    }) + select({
        "//:harfbuzz_text_shaping": MLN_SHAPING_HARFBUZZ_SRCS,
        "//conditions:default": [],
    }),
    hdrs = MLN_LAYER_PLUGIN_HEADERS + MLN_CORE_HEADERS + select({
        ":drawable_renderer": MLN_OPENGL_HEADERS + MLN_DRAWABLES_HEADERS + MLN_DRAWABLES_GL_HEADERS,
        ":metal_renderer": MLN_DRAWABLES_HEADERS + MLN_DRAWABLES_MTL_HEADERS,
        ":webgpu_renderer": MLN_DRAWABLES_HEADERS + MLN_DRAWABLES_WEBGPU_HEADERS,
        "//conditions:default": [],
    }),
    copts = CPP_FLAGS + MAPLIBRE_FLAGS,
    defines = select({
        ":drawable_renderer": [
            "MLN_RENDER_BACKEND_OPENGL=1",
        ],
        ":metal_renderer": [
            "MLN_RENDER_BACKEND_METAL=1",
        ],
        ":webgpu_renderer": [
            "MLN_RENDER_BACKEND_WEBGPU=1",
        ],
    }) + select({
        "@platforms//os:ios": ["GLES_SILENCE_DEPRECATION=1"],
        "//conditions:default": [],
    }) + select({
        "//:harfbuzz_text_shaping": ["MLN_TEXT_SHAPING_HARFBUZZ=1"],
        "//conditions:default": [],
    }),
    includes = [
        "include",
        "src",
    ] + select({
        ":metal_renderer": [
            "vendor/metal-cpp",
        ],
        "//conditions:default": [],
    }) + select({
        "//:harfbuzz_text_shaping": [
            "vendor/freetype/include",
            "vendor/harfbuzz/src",
        ],
        "//conditions:default": [],
    }),
    local_defines = [
        r"MLN_VERSION_REV=\"standalone\"",
    ],
    visibility = ["//visibility:public"],
    deps = [
        ":mbgl-core-generated-private-artifacts",
        ":mbgl-core-generated-public-artifacts",
        "//vendor:boost",
        "//vendor:earcut.hpp",
        "//vendor:eternal",
        "//vendor:expected-lite",
        "//vendor:maplibre-native-base",
        "//vendor:parsedate",
        "//vendor:pmtiles",
        "//vendor:polylabel",
        "//vendor:protozero",
        "//vendor:rapidjson",
        "//vendor:supercluster.hpp",
        "//vendor:unique_resource",
        "//vendor:unordered_dense",
        "//vendor:vector-tile",
        "//vendor:wagyu",
        "//vendor/maplibre-tile-spec/cpp:mlt_cpp",
    ] + select({
        "@platforms//os:ios": [
            "//vendor:ghc_filesystem",
            "//vendor:icu",
        ],
        "@platforms//os:osx": [
            "//vendor:icu",
        ],
        "@platforms//os:linux": [
            "//vendor:sqlite",
        ],
        "//conditions:default": [],
    }) + select({
        ":metal_renderer": [
            "//vendor:metal-cpp",
        ],
        "//conditions:default": [],
    }) + select({
        ":harfbuzz_text_shaping": [
            "//vendor:freetype",
            "//vendor:harfbuzz",
        ],
        "//conditions:default": [],
    }) + select({
        ":rust": [
            "//rustutils:rustutilslib",
        ],
        "//conditions:default": [
            "//vendor:csscolorparser",
        ],
    }),
)

# Selects the rendering implementation to utilize in the core

string_flag(
    name = "renderer",
    build_setting_default = "drawable",
    values = [
        "drawable",
        "metal",
        "webgpu",
    ],
)

config_setting(
    name = "drawable_renderer",
    flag_values = {
        ":renderer": "drawable",
    },
)

config_setting(
    name = "metal_renderer",
    flag_values = {
        ":renderer": "metal",
    },
)

config_setting(
    name = "webgpu_renderer",
    flag_values = {
        ":renderer": "webgpu",
    },
)

# Selects the shaping implementation to utilize in the core

string_flag(
    name = "shaping",
    build_setting_default = "harfbuzz",
    values = [
        "legacy",
        "harfbuzz",
    ],
)

config_setting(
    name = "harfbuzz_text_shaping",
    flag_values = {
        ":shaping": "harfbuzz",
    },
)

config_setting(
    name = "legacy_text_shaping",
    flag_values = {
        ":shaping": "legacy",
    },
)

bool_flag(
    name = "use_rust",
    build_setting_default = False,
    visibility = ["//visibility:public"],
)

config_setting(
    name = "rust",
    flag_values = {
        "//:use_rust": "true",
    },
)

exports_files(
    [
        "LICENSE.md",
        "scripts/style-spec-reference/v8.json",
    ],
    visibility = ["//visibility:public"],
)

npm_link_all_packages(
    name = "node_modules",
)

js_binary(
    name = "generate-style-code-script",
    data = [
        ":node_modules/csscolorparser",
        ":style-code",
        ":style-spec",
    ],
    entry_point = "scripts/generate-style-code.mjs",
)

js_binary(
    name = "generate-shader-code-script",
    entry_point = "shaders/generate_shader_code.mjs",
)

js_library(
    name = "style-spec",
    srcs = ["scripts/style-spec.mjs"],
    data = glob([
        "scripts/style-spec-reference/*.json",
    ]),
    visibility = ["//visibility:public"],
)

js_library(
    name = "style-code",
    srcs = ["scripts/style-code.mjs"],
    visibility = ["//visibility:public"],
    deps = [
        ":node_modules/ejs",
    ],
)

cc_library(
    name = "maplibre_lib",
    srcs = [],
    visibility = ["//visibility:public"],
    deps = select({
        "@platforms//os:macos": ["//platform:macos-objcpp"],
        "//conditions:default": [],
    }),
)
